
#include "ps.h"
#include "pio.h"
#include "ui.h"
#include "logging.h"
#include "zy_encoder.h"
#ifdef ENABLE_ENCODER

EncoderTaskData encoder_tast;
EncoderData encoder_data;
static uint32 vol_up_cut = 0;
static uint32 vol_down_cut = 0;

static int8 Encoder_Scan(void)
{
    int8 ScanResult = encoder_idle;                              //返回编码器扫描结果，用于分析编码器的动作
                                                      //返回值的取值：   encoder_idle：无动作；      encoder_right：正转；           encoder_left：反转；
    int8 pin_a_now, pin_b_now;
    pin_a_now = GET_PIN_A ? 1 : 0;
    pin_b_now = GET_PIN_B ? 1 : 0;
    if (encoder_data.encoder_tpye == 0)               //================一定位对应一脉冲的SK05E01================//
    {                                                 //======================================================//
        if (pin_a_now != encoder_data.encoder_a_last) //以A为时钟，B为数据。正转时AB反相，反转时AB同相
        {
            if (pin_a_now == 0)
            {
                if (pin_b_now == 1) //只需要采集A的上升沿或下降沿的任意一个状态，若A下降沿时B为1，正转
                    ScanResult = encoder_right; //正转

                else //反转
                    ScanResult = encoder_left;
            }
            encoder_data.encoder_a_last = pin_a_now; //更新编码器上一个状态暂存变量
            encoder_data.encoder_b_last = pin_b_now; //更新编码器上一个状态暂存变量
        }
    }
                                                      //======================================================//
    else                                              //================两定位对应一脉冲的SK05E01================//
    {                                                 //======================================================//
        if (pin_a_now != encoder_data.encoder_a_last) //当A发生跳变时采集B当前的状态，并将B与上一次的状态进行对比。
        {                                             //若A 0->1 时，B 1->0 正转；若A 1->0 时，B 0->1 正转；
                                                      //若A 0->1 时，B 0->1 反转；若A 1->0 时，B 1->0 反转
            if (pin_a_now == 1)                       // SK05E01_A和上一次状态相比，为上升沿
            {
                if ((encoder_data.encoder_b_last == 1) && (pin_b_now == 0)) // SK05E01_B和上一次状态相比，为下降沿
                    ScanResult = encoder_right;                                         //正转

                if ((encoder_data.encoder_b_last == 0) && (pin_b_now == 1)) // SK05E01_B和上一次状态相比，为上升沿
                    ScanResult = encoder_left;                                        //反转

                //>>>>>>>>>>>>>>>>下面为正转一次再反转或反转一次再正转处理<<<<<<<<<<<<<<<<//
                if ((encoder_data.encoder_b_last == pin_b_now) && (pin_b_now == 0)) // A上升沿时，采集的B不变且为0
                    ScanResult = encoder_right;                                                 //正转

                if ((encoder_data.encoder_b_last == pin_b_now) && (pin_b_now == 1)) // A上升沿时，采集的B不变且为1
                    ScanResult = encoder_left;                                                //反转
            }

            else // SK05E01_A和上一次状态相比，为下降沿
            {
                if ((encoder_data.encoder_b_last == 1) && (pin_b_now == 0)) // SK05E01_B和上一次状态相比，为下降沿
                    ScanResult = encoder_left;                                        //反转

                if ((encoder_data.encoder_b_last == 0) && (pin_b_now == 1)) // SK05E01_B和上一次状态相比，为上升沿
                    ScanResult = encoder_right;                                         //正转

                //>>>>>>>>>>>>>>>>下面为正转一次再反转或反转一次再正转处理<<<<<<<<<<<<<<<<//
                if ((encoder_data.encoder_b_last == pin_b_now) && (pin_b_now == 0)) // A上升沿时，采集的B不变且为0
                    ScanResult = encoder_left;                                                //反转

                if ((encoder_data.encoder_b_last == pin_b_now) && (pin_b_now == 1)) // A上升沿时，采集的B不变且为1
                    ScanResult = encoder_right;                                                 //正转
            }
            encoder_data.encoder_a_last = pin_a_now; //更新编码器上一个状态暂存变量
            encoder_data.encoder_b_last = pin_b_now; //更新编码器上一个状态暂存变量
        }
    }
    return ScanResult; //返回值的取值：   encoder_idle：无动作；      encoder_right：正转；           encoder_left：反转；
}

static void Encoder_Handler(Task task, MessageId id, Message msg)
{
    UNUSED(task);
    UNUSED(msg);
    int8 encoder_rut;
    switch (id)
    {
    case ENCODER_START_SCAN:
        encoder_rut = Encoder_Scan();
        if (encoder_rut != encoder_idle)
        {
            if (encoder_rut == encoder_left)
            {
                DEBUG_LOG_VERBOSE("Left\n");
                vol_down_cut++;
            }else if (encoder_rut == encoder_right)
            {
                DEBUG_LOG_VERBOSE("Right\n");
                vol_up_cut++;
            }
        }
        MessageCancelAll(EncoderGetTask(), ENCODER_START_SCAN);
        MessageSendLater(EncoderGetTask(), ENCODER_START_SCAN, 0, ENCODER_SCAN_PERIOD_MS);
        break;
    case ENCODER_STOP_SCAN:
        MessageCancelAll(EncoderGetTask(), ENCODER_START_SCAN);
        MessageCancelAll(EncoderGetTask(), ENCODER_ACCEPT_VOL_ADJUST);
        break;
    case ENCODER_ACCEPT_VOL_ADJUST:
        if ((vol_up_cut != 0) || (vol_down_cut != 0))
        {
            if ((vol_up_cut != 0) && (vol_down_cut != 0))
            {
                vol_up_cut = 0;
                vol_down_cut = 0;
            }else
            {
                if (vol_up_cut)
                {
                    vol_up_cut--;
                    Ui_InjectUiInput(ui_input_volume_up);
                }else if (vol_down_cut)
                {
                    vol_down_cut--;
                    Ui_InjectUiInput(ui_input_volume_down);
                }
            }
        }
        MessageCancelAll(EncoderGetTask(), ENCODER_ACCEPT_VOL_ADJUST);
        MessageSendLater(EncoderGetTask(), ENCODER_ACCEPT_VOL_ADJUST, 0, ENCODER_VOL_ADJUST_PERIOD_MS);
        break;
    default:
        break;
    }
}

void Encoder_Init(void)
{
    EncoderTaskData *theuser = EncoderGetTaskData();
    /* 初始化任务 */
    memset(theuser, 0, sizeof(*theuser));
    theuser->task.handler = Encoder_Handler;
    /* 初始化检测pio */
    PioSetMapPins32Bank(PIO_BANK(ENCODER_PIN_A), ENCODER_PIN_A_MASK, ENCODER_PIN_A_MASK);
    PioSetDir32Bank(PIO_BANK(ENCODER_PIN_A), ENCODER_PIN_A_MASK, 0);        //设置A B输入模式
    PioSet32Bank(PIO_BANK(ENCODER_PIN_A), ENCODER_PIN_A_MASK, 0);           //设置下拉
    PioSetStrongBias32Bank(PIO_BANK(ENCODER_PIN_A), ENCODER_PIN_A_MASK, 0); //设置弱拉

    PioSetMapPins32Bank(PIO_BANK(ENCODER_PIN_B), ENCODER_PIN_B_MASK, ENCODER_PIN_B_MASK);
    PioSetDir32Bank(PIO_BANK(ENCODER_PIN_B), ENCODER_PIN_B_MASK, 0);        //设置A B输入模式
    PioSet32Bank(PIO_BANK(ENCODER_PIN_B), ENCODER_PIN_B_MASK, 0);           //设置下拉
    PioSetStrongBias32Bank(PIO_BANK(ENCODER_PIN_B), ENCODER_PIN_B_MASK, 0); //设置弱拉
    /* 初始化编码器默认状态  */
    encoder_data.encoder_tpye = 1;
    encoder_data.encoder_a_last = GET_PIN_A ? 1 : 0;
    encoder_data.encoder_b_last = GET_PIN_B ? 1 : 0;
    vol_up_cut = 0;
    vol_down_cut = 0;
    /* 开机3秒后启动编码器状态检测  */
    MessageSendLater(EncoderGetTask(), ENCODER_START_SCAN, 0, 3000);
    MessageSendLater(EncoderGetTask(), ENCODER_ACCEPT_VOL_ADJUST, 0, 3001);
}

void Encoder_DeInit(void)
{
    MessageSendLater(EncoderGetTask(), ENCODER_STOP_SCAN, 0, 0);
}
#endif
